﻿using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.Linq;
using System.ServiceModel.DomainServices.Client;
using Caliburn.Micro;
using Coproject.Events;
using Coproject.Framework;
using Coproject.ViewModels.Interfaces;
using Coproject.Web.Models;
using Coproject.Web.Services;

namespace Coproject.ViewModels
{
	[ExportModule(30, "To Do")]
	public class ToDoListsViewModel : Conductor<IToDoItemEditor>.Collection.OneActive, IModule, IHandle<ToDoItemUpdatedEvent>
	{
		[Import(RequiredCreationPolicy = CreationPolicy.NonShared)]
		public IBusyWatcher Busy { get; set; }

		public string Description { get; private set; }

		public string Filter { get; set; }
		public IEnumerable<ToDoList> Lists { get; private set; }

		[ImportingConstructor]
		public ToDoListsViewModel(IEventAggregator eventAggregator)
		{
			Description = "To-do lists";

			eventAggregator.Subscribe(this);
		}

		public IEnumerable<IResult> LoadData()
		{
			using (Busy.GetTicket())
			{
				CoprojectContext context = new CoprojectContext();
				EntityQuery<ToDoList> query = context.GetToDoListsWithItemsQuery().OrderByDescending(l => l.CreatedDate);

				if (!Filter.IsNullOrWhiteSpace())
				{
					// query = query.Where(x => x.Name.Contains(Filter)); // if case insensitive database
					string lowerFilter = Filter.ToLower(); // if defined there and not inlined into the query, will be evaluated here and not on the server (could be slightly faster)
					query = query.Where(x => x.Name.ToLower().Contains(lowerFilter)); // if case sensitive database
				}

				var result = new LoadDataResult<ToDoList>(context, query);
				yield return result;

				Lists = result.Result.Entities;
				NotifyOfPropertyChange(() => Lists);
			}
		}

		public IEnumerable<IResult> OpenItemDetail(ToDoItem item)
		{
			var editor = Items.FirstOrDefault(x => x.Item.ToDoItemID == item.ToDoItemID);
			if (editor == null)
			{
				editor = IoC.Get<IToDoItemEditor>();
				yield return editor.Setup(item.ToDoItemID).ToSequential();
			}

			ActivateItem(editor);
			yield break;
		}

		public void Handle(ToDoItemUpdatedEvent message)
		{
			LoadData().ToSequential().Execute(null);
		}
	}
}
